#pragma once

#include <glm/glm.hpp>
#include <vector>
#include "GameObject.h"
#include "Light.h"
#include "../ResourceManagement/Material.h"
#include "../ResourceManagement/IndexBuffer.h"
#include "../ResourceManagement/VertexBuffer.h"
#include "../ResourceManagement/MeshMgr.h"
#include "../ResourceManagement/ResourceMgr.h"

class MeshObject : public GameObject {

public:

	struct Submesh {

		MeshResource::Submesh* m_SubmeshResource;
		MeshObject* m_Mesh;

		Submesh(MeshObject* meshObj, MeshResource::Submesh* submeshRes) {
			m_SubmeshResource = submeshRes;
			m_Mesh = meshObj;
		}

		const std::vector<Light*>& getLights() {
			return m_Mesh->getLights();
		}

		const glm::mat4 getTransform() {
			return m_Mesh->getTransform();
		}

		const Material& getMaterial() {
			return m_Mesh->getMaterial(m_SubmeshResource->m_Index);
		}

		const VertexBuffer& getVertexBuffer() {
			return *m_SubmeshResource->m_VertexBuffer;
		}

		const IndexBuffer& getIndexBuffer() {
			return *m_SubmeshResource->m_IndexBuffer;
		}
	};

	typedef std::vector<Submesh*> Submeshes;
	typedef std::vector<RHANDLE> Handles;
	typedef std::vector<Light*> Lights;

private:

	Lights m_LocalLights;
	Handles m_MaterialHandles;
	Submeshes m_Submeshes;
	RHANDLE m_MeshResourceHandle;

public:
	
	MeshObject(wstring meshIdentifier, std::vector<wstring> materialIdentifiers) {
		m_MeshResourceHandle = MeshMgr::getInstance().Load(meshIdentifier);
		
		m_MaterialHandles.resize(materialIdentifiers.size());
		for(int i=0; i<materialIdentifiers.size(); ++i) {
			m_MaterialHandles[i] = MaterialMgr::getInstance().Load(materialIdentifiers[i]);
		}
	}

	~MeshObject() {
		for (int i=0; i<m_Submeshes.size(); ++i)
			delete m_Submeshes[i];
	}

	const Submesh& getSubmesh(int index) const {
		return *m_Submeshes[index];
	}

	const Submeshes& getSubmeshes() const {
		return m_Submeshes;
	}

	const Lights& getLights() const {
		return m_LocalLights;
	}

	RHANDLE getMaterialHandle(int index) {
		return m_MaterialHandles[index];
	}

	Material& getMaterial(int index) {
		return MemoryMgr::getInstance().dereference<Material>(getMaterial());
	}

	Handles getMaterialHandles() {
		return m_MaterialHandles;
	}

};

